package com.ithinks.flow.common.config.mutidatasource;

import com.baomidou.mybatisplus.MybatisConfiguration;
import com.baomidou.mybatisplus.entity.GlobalConfiguration;
import com.baomidou.mybatisplus.mapper.LogicSqlInjector;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.plugins.PerformanceInterceptor;
import com.baomidou.mybatisplus.spring.MybatisSqlSessionFactoryBean;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.type.JdbcType;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;

import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;

/**
 * @Description
 * @ClassName MutiDataSourceConfig
 * @Author MR.LI
 * @date 2020.12.02 12:39
 */
@Configuration
public class MutiDataSourceConfig {

    @Value("classpath*://mybatis-mapper/*Mapper.xml")
    private String mapperLocations;

    @Bean
    @ConfigurationProperties(prefix = "mysql.spring.datasource")
    public DataSource mysqlDataSource(){
        return DataSourceBuilder.create().build();
    }
    /**
     * PG数据源
     * @return
     */
    @Bean(name = "postgresqlDataSource")
    @ConfigurationProperties(prefix = "postgresql.spring.datasource")
    public DataSource postgresqlDataSource() {
        return DataSourceBuilder.create().build();
    }


    /**
     * 多数据源动态切换
     * @param mysqlDataSource
     * @return
     */
    @Bean
    public DataSource multiDataSource(@Qualifier("mysqlDataSource") DataSource mysqlDataSource )
    {
        Map<Object,Object> target = new HashMap<>();
        target.put(DataSourceEnum.PG,postgresqlDataSource());
        target.put(DataSourceEnum.MYSQL,mysqlDataSource);

        AbstractRoutingDataSource dataSource = new DynamicDataSource();
        dataSource.setDefaultTargetDataSource(mysqlDataSource);
        dataSource.setTargetDataSources(target);
        return dataSource;
    }

    /**
     * mybatis-plus分页插件
     * @return
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        return new PaginationInterceptor();
    }


    @Bean
    public SqlSessionFactory sqlSessionFactory(
            PaginationInterceptor paginationInterceptor,@Qualifier("multiDataSource") DataSource mutiDataSource) throws Exception {
        MybatisSqlSessionFactoryBean sqlSessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(mutiDataSource);
        MybatisConfiguration configuration = new MybatisConfiguration();
        configuration.setJdbcTypeForNull(JdbcType.NULL);
        configuration.setMapUnderscoreToCamelCase(true);
        configuration.setCacheEnabled(false);
        sqlSessionFactoryBean.setConfiguration(configuration);
        sqlSessionFactoryBean.setPlugins(new Interceptor[]{
                paginationInterceptor
        });
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        sqlSessionFactoryBean.setMapperLocations(resolver.getResources(mapperLocations));  //配置mapper位置
        sqlSessionFactoryBean.setGlobalConfig(globalConfiguration());
        return sqlSessionFactoryBean.getObject();
    }
    /**
     * mybatis-plus中SQL执行效率插件，生产环境可以关闭
     */
    @Bean
    public PerformanceInterceptor performanceInterceptor() {
        return new PerformanceInterceptor();
    }

    @Bean
    public GlobalConfiguration globalConfiguration() {
        GlobalConfiguration conf = new GlobalConfiguration(new LogicSqlInjector());
        conf.setLogicDeleteValue("-1");
        conf.setLogicNotDeleteValue("1");
        conf.setIdType(0);
        conf.setMetaObjectHandler(new MyMetaObjectHandler());
        conf.setDbColumnUnderline(true);
        conf.setRefresh(true);
        return conf;
    }
}
